<?php

namespace addon\qcloud_sms;

use think\facade\Cache;

class Back{
    
    protected $config = [
        'app_id'     => '537922920000043359',
        'app_secret' => '851641d0e46873befa298339f6fcc71d',
    ];
    
    /**
     * 发送手机短信
     *
     * @param unknown $mobile 手机号
     * @param json格式参数 res_code string 同步结果代码，返回0表示成功，其它值标识失败，后续在定义 res_message string 成功返回：Success；错误返回：错误信息 identifier string 成功返回：短信唯一标识；错误返回：返回空
     */
    public function send($phone, $code)
    {
        header('Content-Type: text/html; charset=utf-8');
        $param = '{"param1":"'.$code.'","param2":"10"}';
        return $this->_runSend2($phone, $param, '91005364');
    }
    
    /**
     * 发送短信接口 res_code：同步结果代码，返回0表示成功，其它值标识失败，后续在定义 res_message：成功返回：Success；错误返回：错误信息 identifier：成功返回：短信唯一标识；错误返回：返回空.
     *
     * @param unknown $access_token
     * @param unknown $phone
     * @param unknown $param
     *
     * @return unknown
     */
    private function _runSend2($phone, $param, $template_id)
    {
        set_time_limit(0);
        $params = [];
        $params['timestamp'] = date('Y-m-d H:i:s');
        $params['app_id'] = $this->config['app_id'];
        $params['access_token'] = $this->getTianyiToken();
        $params['acceptor_tel'] = $phone;
        $params['template_id'] = $template_id;
        $params['template_param'] = $param;
        $params['sign'] = $this->_makeSign($params);
        $json = $this->_apiPost('http://api.189.cn/v2/emp/templateSms/sendSms', $params);
        $json['sms_platform'] = 1;
        return $json;
    }
    
    /**
     * 加密.
     *
     * @param unknown $params
     *
     * @return string
     */
    private function _makeSign($params)
    {
        ksort($params);
        $plaintext = $this->_buildPlainText($params);
    
        return rawurlencode(base64_encode(hash_hmac('sha1', $plaintext, $this->config['app_secret'], true)));
    }
    
    /**
     * 配置短信接口.
     *
     * @return unknown
     */
    protected function getTianyiToken()
    {
        $token = Cache::get('sys_tianyi_token1');
        if ($token['expires_in'] < (time() - 20 * 86400)) { // 目前配置20天更新一次token
            $url = 'https://oauth.api.189.cn/emp/oauth2/v3/access_token';
            $params_array = [
                'app_id'     => $this->config['app_id'],
                'app_secret' => $this->config['app_secret'],
                'grant_type' => 'client_credentials',
            ];
            $result = $this->_apiPost($url, $params_array, true);
            if ($result && 0 == $result['res_code']) {
                Cache::set('sys_tianyi_token', [
                    'access_token' => $result['access_token'],
                    'expires_in'   => time() + $result['expires_in'] - 100,
                ]);
    
                return $result['access_token'];
            } else {
                throw new \Exception('获取token错误');
            }
        } else {
            return $token['access_token'];
        }
    }
    
    private function _buildPlainText($params)
    {
        if (is_array($params)) {
            $array = [];
            foreach ($params as $key => $value) {
                $value = $this->_buildPlainText($value);
                $array[] = $key.'='.$value;
            }
    
            return implode('&', $array);
        }
    
        return $params;
    }
    
    private function _apiPost($url, $params = [], $https = false)
    {
        $args = $this->_buildPlainText($params);
        $session = curl_init($url);
        curl_setopt($session, CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($session, CURLOPT_HEADER, false);
        curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($session, CURLOPT_HTTPHEADER, [
            'Expect:',
        ]);
        curl_setopt($session, CURLOPT_POSTFIELDS, $args);
        if ($https) {
            curl_setopt($session, CURLOPT_SSL_VERIFYPEER, 0);
            curl_setopt($session, CURLOPT_SSL_VERIFYHOST, 2);
        }
        $rawResponse = curl_exec($session);
        curl_close($session);
    
        return json_decode($rawResponse, true);
    }
}